home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / PowerPlant / AGA Classes 1.2 / Buttons / LAGAIconButton.cp < prev    next >
Encoding:
Text File  |  1996-06-30  |  10.2 KB  |  329 lines  |  [TEXT/CWIE]

  1. // ===========================================================================
  2. //    LAGAIconButton.cp
  3. // ===========================================================================
  4. //    “Apple Grayscale Appearance” compliant (almost) icon button
  5. //    Copyright © 1996 Chrisoft (Christophe ANDRES)  All rights reserved.
  6. //
  7. //    You may use this source code in any application (commercial, shareware, freeware,
  8. //    postcardware, etc), but not remove this notice (no need to acknowledge the use of
  9. //    this class in the about box)
  10. //    You may not sell this source code in any form. This source code may be placed on 
  11. //    publicly accessable archive sites and source code disks. It may not be placed on 
  12. //    profit archive sites and source code disks without the permission of the author, 
  13. //    Christophe ANDRES.
  14. //    
  15. //        This source code is distributed in the hope that it will be useful,
  16. //        but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. //        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  18. //
  19. //    If you make any change or improvement on this class, please send the improved/changed
  20. //    version to : chrisoft@calva.net or Christophe ANDRES
  21. //                                     20, rue Prosper Mérimée
  22. //                                     67100 STRASBOURG
  23. //                                     FRANCE
  24. //
  25. // ===========================================================================
  26. //    LAGAIconButton.h            <- double-click + Command-D to see class declaration
  27. //
  28. //    LAGAIconButton is my implementation of the “Apple Grayscale Appearance for System 7.5”
  29. //        Icon Buttons with the exception of the pressed state. The pressed state is my own kind,
  30. //        because I (and my customers) found it nicer than Apple's ;-)
  31. //
  32. //        The button supports icon families or cicn (use 'ICN#' and 'cicn' in constructor. To
  33. //        get the best result, the size of the button should be 5 pixels more than the icon (so for
  34. //        a 32X32 icon, the minimum size should be 37X37)
  35. //
  36. //        if mRadioBehavior is set, the Icon Button acts as a RadioButton and can be used with
  37. //        a radio group
  38. //
  39. //        This class requires AGAColors.cp to be present in your project
  40. //
  41. //        Version : 1.2
  42. //
  43. //        Change History (most recent first, date in US form : mm/dd/yy):
  44. //
  45. //                        06/30/96    ca        Public release of version 1.2
  46. //                        06/27/96    ca        Changed checks for disabled state (check on triState_On instead of triState_Off)
  47. //                                                            in order that triState_Latent state is drawn as disabled
  48. //                        06/04/96    ca        Added static RegisterClass for easier class registration
  49. //                                                        Increased version to 1.2
  50. //                        06/01/96    ms        Changes brought by Marco Sandri <msandri@mbox.vol.it>
  51. //                                                        Changes made to avoid icon "flicker" during pressing
  52. //                        05/15/96    ca        Replaced HasAGAColors by PaneInColor (see note in AGAColors.h)
  53. //                        05/11/96    ca        Increased version to 1.1
  54. //                                                        Added copy constructor
  55. //                                                        Added "on the fly" constructor
  56. //                                                        Replaced UEnvironment::HasFeature(env_SupportsColor) with HasAGAColors
  57. //                                                        Added change history
  58. //                        04/22/96    ca        class made available by Christophe ANDRES <chrisoft@calva.net>
  59. //                                                        (version 1.0)
  60. //
  61. //        To Do:
  62. //
  63.  
  64. #include "LAGAIconButton.h"
  65. #include "AGAColors.h"
  66. #include <UDrawingState.h>
  67. #include <PP_Messages.h>
  68. #include <PP_Resources.h>
  69.  
  70. // begin <06/04/96 ca>
  71. void LAGAIconButton::RegisterClass ()
  72.  
  73. {
  74.     URegistrar::RegisterClass(LAGAIconButton::class_ID, (ClassCreatorFunc)LAGAIconButton::CreateAGAIconButtonStream);
  75. }
  76. // end <06/04/96 ca>
  77.  
  78. LAGAIconButton* LAGAIconButton::CreateAGAIconButtonStream (LStream *inStream)
  79.  
  80. {
  81.     return(new LAGAIconButton(inStream));
  82. }
  83.  
  84. //-------Constructors-------------------------------------------------------------------------------------------------
  85.  
  86. LAGAIconButton::LAGAIconButton ()
  87.  
  88. {
  89.     mIconType = 'ICN#';
  90.     mIconID = resID_Undefined;
  91.     mIcon = nil;
  92.     mRadioBehavior = false;
  93. }
  94.  
  95. LAGAIconButton::LAGAIconButton (LStream    *inStream) : LControl(inStream)
  96.  
  97. {
  98.     unsigned char radioBehavior;
  99.     
  100.     mIcon = nil;
  101.     inStream->ReadData(&mIconType, sizeof(OSType));
  102.     inStream->ReadData(&mIconID, sizeof(ResIDT));
  103.     inStream->ReadData(&radioBehavior, sizeof(unsigned char));
  104.     mRadioBehavior = (radioBehavior != 0);
  105.     if (mRadioBehavior)
  106.         mMaxValue = 1;
  107.     if (mIconType != 'cicn' && mIconType != 'ICN#')
  108.         delete this;
  109. }
  110.  
  111. //    begin <05/11/96 ca>
  112. LAGAIconButton::LAGAIconButton (const LAGAIconButton &inOriginal) : LControl(inOriginal)
  113.  
  114. {
  115.     mIcon = nil;
  116.     mIconType = inOriginal.mIconType;
  117.     mIconID = inOriginal.mIconID;
  118.     mRadioBehavior = inOriginal.mRadioBehavior;
  119.     if (mRadioBehavior)
  120.         mMaxValue = 1;
  121.     if (mIconType != 'cicn' && mIconType != 'ICN#')
  122.         delete this;
  123. }
  124.  
  125. LAGAIconButton::LAGAIconButton (const SPaneInfo &inPaneInfo, MessageT inClickedMessage, OSType inIconType,
  126.                                                                 ResIDT inIconID, Boolean inRadioButtonBehavior)
  127.                                                             : LControl(inPaneInfo, inClickedMessage, 0, 0, 1)
  128. {
  129.     mIcon = nil;
  130.     mIconType = inIconType;
  131.     mIconID = inIconID;
  132.     mRadioBehavior = inRadioButtonBehavior;
  133.     if (mRadioBehavior)
  134.         mMaxValue = 1;
  135.     if (mIconType != 'cicn' && mIconType != 'ICN#')
  136.         delete this;
  137. }
  138. //    end <05/11/96 ca>
  139.  
  140. LAGAIconButton::~LAGAIconButton ()
  141.  
  142. {
  143.     if (mIcon != nil)
  144.         DisposeCIcon(mIcon);
  145. }
  146.  
  147. //-------Utilities--------------------------------------------------------------------------------------------------
  148.  
  149. void LAGAIconButton::HotSpotResult (Int16    inHotSpot)
  150.  
  151. {
  152.                                                             // Undo Button hilighting
  153.     if (!mRadioBehavior)
  154.         {
  155.             HotSpotAction(inHotSpot, false, true);
  156.             BroadcastValueMessage();        // Although value doesn't change,
  157.                                                                     //   send message to inform Listeners
  158.                                                                     //   that button was clicked
  159.         }
  160.     else
  161.         {
  162.             // In the Mac interface, clicking on a RadioButton always
  163.             // turns it on (or leaves it on). The standard way to turn
  164.             // off a RadioButton is to turn on another one in the
  165.             // same Radio Group. A Radio Group will normally be a
  166.             // Listener of a RadioButton.
  167.          
  168.             if (mValue != Button_On)                                                                                                                                                        //    <06/01/96    ms>
  169.                 SetValue(Button_On);
  170.         }
  171. }
  172.  
  173. void LAGAIconButton::HotSpotAction (Int16 inHotSpot, Boolean inCurrInside, Boolean inPrevInside)
  174.  
  175. {
  176.                                     // Draw if cursor moved from IN to OUT
  177.                                     //   or from OUT to IN
  178.     if (inCurrInside != inPrevInside && (!mRadioBehavior || mValue != Button_On))                                                        //    <06/01/96    ms>
  179.         {    
  180.             FocusDraw();
  181.             DrawGraphic(inCurrInside);
  182.         }
  183. }
  184.  
  185. void LAGAIconButton::SetValue (Int32    inValue)
  186.  
  187. {
  188.     
  189.     if (!mRadioBehavior)
  190.         {
  191.             LControl::SetValue(inValue);
  192.         }
  193.     else
  194.         {
  195.             if (inValue < mMinValue)
  196.                 inValue = mMinValue;
  197.             else
  198.                 if (inValue > mMaxValue)
  199.                     inValue = mMaxValue;
  200.             mValue = inValue;
  201.             // If turning RadioButton on, broadcast message so that the
  202.             // RadioGroup (if present) will turn off the other RadioButtons
  203.             // in the group.
  204.     
  205.             if (inValue == Button_On)
  206.                 {
  207.                     BroadcastValueMessage();
  208.                     BroadcastMessage(msg_ControlClicked, (void*) this);
  209.                 }
  210.             Draw(nil);                                                                                                                                                                                //    <06/01/96    ms>
  211.         }
  212. }
  213.  
  214. //-------Drawers----------------------------------------------------------------------------------------------------
  215.  
  216. void LAGAIconButton::DrawSelf ()
  217.  
  218. {
  219.     DrawGraphic(false);
  220. }
  221.  
  222. void LAGAIconButton::DrawGraphic (Boolean inPushed)
  223.  
  224. {
  225.     StColorPenState theState;
  226.     Rect frame;
  227.     long theValue = (mRadioBehavior ? mValue : 0);
  228.     Boolean down = inPushed || (theValue != 0);
  229.     Boolean hasColor = ::PaneInColor(this);                                                                        //    <05/15/96 ca>
  230.  
  231.     theState.Normalize();
  232.     CalcLocalFrameRect(frame);
  233.     
  234.     //    Draw the black frame;
  235.     ::MoveTo(frame.left + 1, frame.top);
  236.     ::LineTo(frame.right - 2, frame.top);
  237.     ::MoveTo(frame.right - 1, frame.top + 1);
  238.     ::LineTo(frame.right - 1, frame.bottom - 2);
  239.     ::MoveTo(frame.right - 2, frame.bottom - 1);
  240.     ::LineTo(frame.left + 1, frame.bottom - 1);
  241.     ::MoveTo(frame.left, frame.bottom - 2);
  242.     ::LineTo(frame.left, frame.top + 1);
  243.     
  244.     //    Draw the inside (w/o the Icon)
  245.     ::InsetRect(&frame, 1, 1);
  246.     if (hasColor)
  247.         {
  248.             ApplyForeAndBackColors();
  249.             if (down)
  250.                 ::RGBBackColor(&gAGAColorArray[4]);
  251.         }
  252.     ::EraseRect(&frame);
  253.     
  254.     //    Draw the shadows
  255.     if (hasColor)
  256.         {
  257.             ::RGBForeColor(&gAGAColorArray[7]);
  258.             if (down)
  259.                 {
  260.                     ::MoveTo(frame.left, frame.bottom - 1);
  261.                     ::LineTo(frame.left, frame.top);
  262.                     ::LineTo(frame.right - 1, frame.top);
  263.                 }
  264.             else
  265.                 {
  266.                     ::MoveTo(frame.right - 1, frame.top);
  267.                     ::LineTo(frame.right - 1, frame.bottom - 1);
  268.                     ::LineTo(frame.left, frame.bottom - 1);
  269.                     ::MoveTo(frame.right - 2, frame.top + 1);
  270.                     ::LineTo(frame.right - 2, frame.bottom - 2);
  271.                     ::LineTo(frame.left + 1, frame.bottom - 2);
  272.                     ::ForeColor(whiteColor);
  273.                     ::MoveTo(frame.left, frame.bottom - 2);
  274.                     ::LineTo(frame.left, frame.top);
  275.                     ::LineTo(frame.right - 2, frame.top);
  276.                 }
  277.         }
  278.     
  279.     //    Draw the Icon
  280.     SDimension16 theSize;
  281.     Rect drawFrame;
  282.     
  283.     CalcLocalFrameRect(frame);
  284.     GetFrameSize(theSize);
  285.     if (GetIconID() != resID_Undefined)
  286.         if (mIconType == 'cicn')
  287.             {
  288.                 if (mIcon == nil)
  289.                     mIcon = ::GetCIcon(GetIconID());
  290.                 if (mIcon != nil)
  291.                     {
  292.                         drawFrame = (*mIcon)->iconBMap.bounds;
  293.                         if (theSize.width < (drawFrame.right + 5))
  294.                             drawFrame.right = theSize.width - 5;
  295.                         if (theSize.height < (drawFrame.bottom + 5))
  296.                             drawFrame.bottom = theSize.height - 5;
  297.                         short hPos = (((theSize.width - drawFrame.right) / 2) + frame.left) + ((down && hasColor) ? 1 : 0);
  298.                         short vPos = (((theSize.height - drawFrame.bottom) / 2) + frame.top) + ((down && hasColor) ? 1 : 0);
  299.                         drawFrame.left += hPos;
  300.                         drawFrame.right += hPos;
  301.                         drawFrame.top += vPos;
  302.                         drawFrame.bottom += vPos;
  303.                         
  304.                         ::PlotCIconHandle(&drawFrame, atNone, (mEnabled == triState_On) ? ttNone : ttDisabled, mIcon);                //    <06/27/96    ca>
  305.                     }
  306.             }
  307.         else
  308.             {
  309.                 if ((theSize.width < 37) || (theSize.height < 37))
  310.                     ::SetRect(&drawFrame, 0, 0, 16, 16);
  311.                 else
  312.                     ::SetRect(&drawFrame, 0, 0, 32, 32);
  313.                 short hPos = (((theSize.width - drawFrame.right) / 2) + frame.left) + ((down && hasColor) ? 1 : 0);
  314.                 short vPos = (((theSize.height - drawFrame.bottom) / 2) + frame.top) + ((down && hasColor) ? 1 : 0);
  315.                 drawFrame.left += hPos;
  316.                 drawFrame.right += hPos;
  317.                 drawFrame.top += vPos;
  318.                 drawFrame.bottom += vPos;
  319.                 
  320.                 ::PlotIconID(&drawFrame, atNone, (mEnabled == triState_On) ? ttNone : ttDisabled, GetIconID());                        //    <06/27/96    ca>
  321.             }
  322.     if (!hasColor && down)
  323.         {
  324.             ::InsetRect(&frame, 1, 1);
  325.             ::InvertRect(&frame);
  326.         }
  327. }
  328.  
  329.